package org.oproject.rmi.hessian.core.invoke.impl;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import org.oproject.rmi.hessian.core.config.BaseConfig;
import org.oproject.rmi.hessian.core.context.HessianContext;
import org.oproject.rmi.hessian.core.invoke.Invokor;
import org.oproject.rmi.hessian.core.job.HessianJob;
import org.oproject.rmi.hessian.core.job.SecurityHessianJob;
import org.oproject.rmi.hessian.core.logger.LogFactory;
import org.oproject.rmi.hessian.core.logger.Logger;
import org.oproject.rmi.hessian.core.service.ServiceManager;
import org.oproject.rmi.hessian.exception.HessainJobException;
import org.oproject.rmi.hessian.exception.HessianRemoteInvokeException;

public class LocalInvokor implements Invokor
{
	private static Logger log = LogFactory.getLogger(LocalInvokor.class);
	
	private static BaseConfig baseConfig = BaseConfig.getInstance();
	
	private static ServiceManager serviceManager = null;
	
	@Override
	public Object invoke(HessianJob hessianJob) throws HessianRemoteInvokeException
	{	
		//注册jobid
		HessianContext.regiestLocalContext(hessianJob);
		
		if(null == hessianJob || !hessianJob.validate())
		{
			log.error("hessian job is not standard: maybe hessian job is null or service name is null");
			
			throw new HessainJobException("hessian job is not standard: maybe hessian job is null or service name is null");
		}
		
		if(log.isDebugEnabled())
		{
			log.debug("invoke : " + hessianJob.getServiceName());
		}
		
		//是否需要执行服务的标识符
		boolean _needExecute = true;
		
		if(baseConfig.isSecurity())
		//如果是通讯安全的，则要进行安全验证
		{
			if(hessianJob instanceof SecurityHessianJob)
			{
				/*
				 * TODO 进行安全验证
				 */
			}
			else
			{
				_needExecute = false;
			}
		}
		
		if(_needExecute)
		{
			try
			{
				return this.getServiceManager().invokeService(hessianJob);
			}
			catch (Exception e)
			{
				e.printStackTrace();
				
				if(log.isDebugEnabled())
				{
					log.debug(e.getMessage());
				}
				
				throw new HessainJobException(e.getMessage(), e.getCause());
			}
		}
		else
		{
			/*
			 * TODO 需要返回一个异常信息
			 */
			return null;
		}
	}
	
	/**
	 * 设置服务管理类
	 * @param _serviceManager
	 */
	public static void regiestServiceManager(ServiceManager _serviceManager)
	{
		serviceManager = _serviceManager;
	}
	
	/**
	 * 设置服务管理类
	 * @param _serviceManager
	 */
	public static void regiestServiceManager()
	{
		log.info("<-- 开始注册服务管理对象 -->");

		try 
		{
			serviceManager = loadServiceManager();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			
			if(log.isDebugEnabled())
			{
				log.debug(e.getMessage());
			}
			
			throw new HessainJobException(e.getMessage(), e.getCause());
		}	
		
		log.info("<-- 注册服务管理对象成功 -->");
	}
	
	/**
	 * 设置服务管理类
	 * @param _serviceManager
	 * @throws ClassNotFoundException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws NoSuchMethodException 
	 * @throws SecurityException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 */
	private ServiceManager getServiceManager() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException
	{
		if(null == serviceManager)
		{
			serviceManager = loadServiceManager();
		}
		
		return serviceManager;
	}
	
	@SuppressWarnings("unchecked")
	private static ServiceManager loadServiceManager() throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException
	{
		String serviceManagerClass = baseConfig.serviceMangerClass();
		
		log.info("<-- 加载的服务管理：" + serviceManagerClass + " -->");
		
		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		Class<ServiceManager> clazz = (Class<ServiceManager>) Class.forName(serviceManagerClass, false , loader);
		
		Class[] temp = new Class[]{};
		Constructor cons = clazz.getConstructor(temp);
		
		return (ServiceManager)cons.newInstance();
	}
}
